# -*- coding:utf-8 -*-
import os
from time import time

end_sign='",]}:'                            #end sign
hex_sign='1234567890abcdef'
i=0
content=''
coding_list=['utf-8', 'gbk', 'gb2312', 'gb18030']
data={}
def decode_str(data,coding=''):
    if type(data)==type(u''):
        return data
    if coding!='':
        return data.decode(coding,'ignore')
    else:
        for coding in coding_list:
            try:
                rdata=data.decode(coding)
                return rdata
            except:
                pass
        return data.decode('utf-8','ignore')

def encode_attr(value):
    if isinstance(value,bool):
        return str(value).lower()
    elif isinstance(value,(int,float,long)):
        return str(value)
    elif isinstance(value,(str,unicode)):                    #str
        return '"%s"'%value
    elif value==None:                               #None
        return 'null'
    elif isinstance(value,list):                    #list
        list_str=''
        for v in value:
            list_str=list_str+encode_attr(v)+','
        return '[%s]'%list_str[:-1]
    elif isinstance(value,dict):                     #dict
        json_str=''
        for k,v in value.iteritems():
            js_str=encode_attr(v)
            json_str+='"%s":%s,'%(k,js_str)
        return "{%s}"%json_str[:-1]
    else:
        print 'XXXX',value
    
def dumps(obj={}):
    global data
    if obj:
        json_str=encode_attr(obj)
    else:
        json_str=encode_attr(data)
    return json_str
##############################################################

def cnext():
    global i
    return content[i]
def get_next():
    global i
    if i<len(content):
        c=cnext()
        i+=1
        return c
    return None
def get_unicode():
    global hex_sign
    v_value=''
    hexc=''
    while True:
        tcc=get_next()
        if tcc.lower()  in hex_sign:
            hexc+=tcc
            if len(hexc)>=4:
                v_value+=unichr(eval('0x'+hexc))
                break
        else:
            v_value+='\\'
            v_value+='u'
            v_value+=hexc
            v_value+=tcc
            break
    return v_value
def get_name():                             #get name
    v_value=''
    c=get_next()
    while c!='"' and c!=None:
        c=get_next()
        pass
    while True:
        c=get_next()
        if c=='"':
            break
        elif c=='\\':
            tc=get_next()
            if tc=='u':                         #unicode
                v_value+=get_unicode()
            else:
                v_value+=c
                v_value+=tc
        else:
            v_value+=c
    return v_value

def get_str():                              #get value
    v_value=''
    while True:
        c=get_next()
        if c=='"':
            break
        elif c=='\\':
            tc=get_next()
            if tc=='u':                         #unicode
                v_value+=get_unicode()
            else:
                v_value+=c
                v_value+=tc
        else:
            v_value+=c
    return v_value

def get_none(c):                              #get value
    global i
    global end_sign
    v_value=c
    while True:
        c=get_next()
        if c in end_sign:
            i-=1
            break
        else:
            v_value+=c
    if v_value.strip()=='null':
        return None
    else:
        raise Exception('None type error in positon: %d'%i)

def get_bool(c):
    global i
    global end_sign
    cc=c
    while True:
        tc=get_next()
        if tc in end_sign:
            i-=1
            break
        else:
            cc+=tc
    if cc.strip()=='true':
        return True
    elif cc.strip()=='false':
        return False
    else:
        print cc
        raise Exception('bool type error in position: %d'%i)
def get_num(c):
    global i
    global end_sign
    s_num=c
    while True:
        cc=get_next()
        if cc in end_sign:
            i-=1
            break
        else:
            s_num+=cc
    return eval(s_num.strip())
def get_value():
    c=strip_space()
    if c=='"':
        v_value=get_str()
    elif c in 'tf':
        v_value=get_bool(c)
    elif c in '-1234567890e':
        v_value=get_num(c)
    elif c=='n':
        v_value=get_none(c)
    elif c=='[':
        v_value=get_list()
    elif c=='{':
        v_value=get_object()
    return v_value

def get_list():
    global i
    r_list=[]
    c=strip_space()
    if c==']':
        return []
    else:
        i-=1
    while True:
        v_value=get_value()
        r_list.append(v_value)
        c=strip_space()
        if c==',':
            cc=strip_space()
            if cc==']':
                return r_list
            else:
                i-=1
                continue
        elif c==']':
            return r_list
        else:
            raise Exception('list type error in position: %d'%i)

def strip_space():
    while True:
        c=get_next()
        if c not in ' \t\n\r\v\f':
            return c

def get_object():
    global i
    dict1={}
    c=strip_space()
    if c=='}':
        return {}
    else:
        i-=1
    while True:
        v_name=get_name()               #获得名称
        while get_next()!=':':          #过滤冒号
            pass
        v_value=get_value()
        dict1[v_name]=v_value
        c=strip_space()
        if c==',':
            cc=strip_space()
            if cc=='}':
                break
            else:
                i-=1
                continue
        elif c=='}' or c==None:
            break
        else:
            raise Exception(c)
    return dict1

def loads(json_str):
    global i
    global content
    global data
    data={}
    content=decode_str(json_str.strip(),'utf-8')
    i=0
    c=strip_space()
    if True or c=='{' :
        try:
            obj=get_object()
            return obj
        except Exception,e:
            print str(e)
            print i,content[i-20:i],'###',content[i:i+20]
            print 'error happen in position %d'%i
    else:
        print 'error'
        raise Exception('error json string')

def __getitem__(key):
    return data[key]
def __setitem__(key,value):
    data[key]=value
    
def get_attr(obj,attr_str):
    obj.get(attr_str,None)
    
def set_attr(obj,v_name,v_value):
    obj[v_name]=v_value
    return obj
def del_attr(obj,v_name):
    obj.pop(v_name,'')
    return obj

def print_json_dict(obj,i=0):
    if type(obj)==type([]):
        print '    '*i,'['
        for v in obj:
            print_json_dict(v,i+1)
        print '    '*i,']'
    elif type(obj)==type({}):
        print '    '*i,'{'
        for k,v in obj.items():
            print '    '*i,' ',str(k).decode('utf-8'),':'
            print_json_dict(v,i+1)
        print '    '*i,'}'
    else:
        print '    '*i,str(obj).decode('utf-8'),','

#print_json_dict(dict1)

def test(times):
    
    start=time()
    dict1={}
    js_list=[]
    for i in range(times):
        jsobj={}
        jsobj["User"]={}
        jsobj["User"]["UserID"] = 10000
        jsobj["User"]["Age"] = 100
        jsobj["User"]["Name"]={}
        jsobj["User"]["Name"]["FirstName"] = "Han"
        jsobj["User"]["Name"]["LastName"] = "MM"
        jsobj["ishost"] = True
        jsobj["Time"] = "2012-9-19 21:14:30"
        jsobj["ID"] = 10086
        jsobj["Description"] = "对于JSON(JavaScript Object Notation)大家应该不陌生，它是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成"
        jsobj["StrArray"]=[]
        jsobj["StrArray"].append("hello")
        jsobj["StrArray"].append("json")
        jsobj["StrArray"].append("!")
        jsobj["IntArray"]=[]
        jsobj["IntArray"].append(1)
        jsobj["IntArray"].append(2)
        jsobj["IntArray"].append(3)
        jsobj["Price"] = 500.5
        jsobj["Title"] = "JavaScript Object Notation"

        jsobj["objArray"]=[]
        objarray={}
        objarray["Prov"] = "广东"
        objarray["City"] = "广州"
        jsobj["objArray"].append(objarray)
        
        objarray2={}
        objarray2["Prov"] = "湖南"
        objarray2["City"] = "长沙"
        jsobj["objArray"].append(objarray2)
        dict1[i]=jsobj
        #js_list.append(jsobj)
    #dict1["a"]=js_list
    json_str=dumps(dict1)
    end=time()
    xt=end-start
    #print '序列化用时:  '.decode('utf-8'),xt,'秒'.decode('utf-8')
    #print json_str
    
    save_file=os.path.abspath('.').replace('\\','/')+'/json.txt'
    f=open(save_file,'w')
    f.write(json_str)
    f.close()

    f=open(save_file,'r')
    json_str=f.read()
    f.close()
    
    start=time()
    dict1=loads(json_str)
    end=time()
    fxt=end-start

    print '-'*20,'打印其中一项:'.decode('utf-8'),'-'*20
    
    print_json_dict(dict1["0"])
    print '-'*50
    print '序列化'.decode('utf-8'),times,'项'.decode('utf-8')
    print '序列化用时:  '.decode('utf-8'),xt,'秒'.decode('utf-8')
    print '反序列化用时: '.decode('utf-8'),fxt,'秒'.decode('utf-8')
if __name__=='__main__':
    
    test(10000)
##    f=open('d:/tmp/jsonpctest.txt','r')
##    data=f.read()
##    f.close()
##    mj=Myjson()
##    start=time()
##    print mj.loads(data)["a"][0]  #["a"][0]["objArray"]
##    end=time()
##    fxt=end-start
##    print fxt
##    print 'end'




